using System;
using System.Collections.Generic;
using System.Text;
using Petra.Gis.Geometry;
using Petra.Gis.Geometry.Support;

namespace Petra.Gis.DataServices.GDO
{
  public unsafe partial class GeometryFactory
  {
    /***********************************************
     * 28.8.2007
     * 
     * creates Polygon
     * from intergraph blob structure
     * 
     * asida@centrum.cz, initial implementation
     *************************************************/
    private static GeometryBase binaryToPolygon(byte[] vData, int arrayOffset, System.Type parentGeomType)
    {

      /*Guid ingrGUID;
      fixed (byte* bGUID = &vData[arrayOffset])
      {
        ingrGUID = (*((Guid*)bGUID));
      }
      if (ingrGUID == getGuid[GeometryType.Boundary]) { }*/

      Polygon oGeom = new Polygon();
      //create exterior ring geometry
      GeometryBase tmpGeom =  createGeometry(vData, arrayOffset + 20, typeof(Polygon));
      oGeom.Add(tmpGeom);

      int pos;
      fixed (byte* bPtr = &vData[arrayOffset])
      {
        //skip position 0, 16 bytes Boundary GUID
        //get exterior ring byte size, position 16
        int* lGeomSize = (Int32*)(bPtr + 16);

        //process holes
        //skip position 16 + 4 + exteriorRingSize = binary size of holes ;-)
        //skip position 16 + 4 + exteriorRingSize + 4 = collection GUID
        pos = *lGeomSize + 40;
        int* numHoles = (Int32*)(bPtr + pos);

        //step over all holes
        //set pos to binary size of first hole
        pos += 4;
        for (int i = 0; i < *numHoles; i++)
        {
          lGeomSize = (Int32*)(bPtr + pos);
          tmpGeom = createGeometry(vData, (arrayOffset + pos + 4), typeof(Polygon));
          oGeom.Add(tmpGeom);
          pos = pos + 4 + *lGeomSize;
        }
      }
      return oGeom;
    }





    /***********************************************
     * 28.8.2007
     * 
     * creates intergraph blob structure 
     * from Polygon
     * 
     * asida@centrum.cz, initial implementation
     *************************************************/

    private static byte[] polygonToBinary(GeometryBase geometry)
    {
      //cast to Polygon first
      Polygon _polygon = (Polygon)geometry;

      //if only exterior ring, save as Polygon or PathRing, no Boundary header necessary
      if (_polygon.Count == 1)
        return saveGeometryBlob(_polygon[0]);


      Guid gGeomGUID;

      System.IO.MemoryStream oIMStream = new System.IO.MemoryStream();
      System.IO.BinaryWriter mBWriter = new System.IO.BinaryWriter(oIMStream);

      //oIMStream.Position = 0;

      //write Boudary GUID
      gGeomGUID = getGuid[GeometryType.Boundary];
      mBWriter.Write(gGeomGUID.ToByteArray());

      //get exterior geometry blob
      byte[] tmp = saveGeometryBlob(_polygon.Exterior);
      //write Boundary exterior binary size
      mBWriter.Write(tmp.Length);
      //write exterior geometry
      mBWriter.Write(tmp);
      //int exteriorSize = tmp.Length;


      tmp = saveGeometryBlob(_polygon.Holes);
      //call directly GeometryFactory -> collectionItemsToBinary()
      //tmp = collectionItemsToBinary(_polygon, 1);
      mBWriter.Write(tmp.Length);

      //get collection guid and write
      //gGeomGUID = getGuid[GeometryType.Collection];
      //mBWriter.Write(gGeomGUID.ToByteArray());

      //write collection bytes
      mBWriter.Write(tmp);

      return oIMStream.ToArray();
    }
  }
}
